/**************************************************************************
* author - Neuron                                                         *
* date - Sep`2008                                                         *
* this file derives from Linux, including such modification:              *
*   those structs have their names changed.                               *
*   we just build the system without considering about multi-user,        *
*   so those elements that associated with a certain user are eliminated. *
**************************************************************************/
#ifndef _SCHEDULE_H
#define _SCHEDULE_H // NOT COMPLETE YET

#define MAX_NR_TASK (64)

#ifndef NR_OPEN
	#define NR_OPEN (32)
#endif /* NR_OPEN */

#ifndef NR_TASKS
	#define NR_TASKS (64)
#endif /* NR_TASKS */

#ifndef HZ
	#define HZ (100)
#endif /* HZ */

#define FIRST_TASK (task[0])
#define LAST_TASK (task[NR_TASKS - 1])

#define INIT_TASK {} // TODO implementation

#define switchTo(taskId)

/*
 * schedule
 */
void schedule(void);
/*
 * set initial schedule
 */
void scheduleInit(void);
/*
 * make certain task sleep
 */
void sleep(TaskInformation**);
void wake(TaskInformation**);

typedef enum {
	NOT_RUNNABLE = -1; // task not runnable
	RUNNING,           // task running or ready
	WAIT_INT,          // task waiting, interruptable
	WAIT_UNINT,        // task waiting, uninterruptable
	ZOMBIE,            // task terminated, waiting for signal from father process
	STOPPED            // task stopped
} ProcessState;

typedef struct {
	long ctrlWrd; // control word
	long statusWrd; // status word
	long tagWrd; // tag word
	long i387InstructionPtr; // instruction pointer for coprocessor
	long i387CodeSeg; // code segment for coprocessor
	long foo; // memory operand offset
	long fos; // segment for memory operand
	long stSpace[20]; // 80 bytes spaces...
} I387Struct;

typedef struct {
	long backLink; // 16 high bits `0`
	long esp0;
	long ss0; // 16 high bits `0`
	long esp1;
	long ss1; // 16 high bits `0`
	long esp2;
	long ss2; // 16 high bits `0`
	long cr3;
	long eip, eflag;
	long eax, ebx, ecx, edx;
	long esp, ebp, esi, edi;
	long es, cs, ss, ds, fs, gs;
	long ldt;
	long traceBitMap;
	I387Struct i387;
} TaskStateSegment;

typedef struct {
	ProcessState state;
	long counter; // timer
	long priority;
	long signal; // signal bit map
	// struct sigaction sig[32]
	long blocked;
	long exitCode;
	unsigned long codeSegStart, // address for code segment
	              codeSegLength, // length of code segment (byte)
	              codeDateLength, // length of both data segment & code segment (byte)
	              totalLength, // (byte)
	              stackStart; // stack base
	long processId, // pid
	     fatherId; // father process id
	long alarm; // alarm time
	long usrTime, // time ruuning under user state
	     sysTime, // time running under system state
	     childUsrTime, // child process' usrTime
	     childSysTime, // child process' sysTime
	     startTime; // process start time
	unsigned short useMath; // used math-coprocessor
	int tty; // tty nr, -1 if not used
	unsigned short umask;
/*	struct m_inode* processWorkDir, // process working directory
	                root, // root directory
	                executable; // executable file
*///	struct file* fileUsed[NR_OPEN]; // list of used files
//	struct desc_struct ldt[3];
	TaskStateSegment tss;
} TaskInformation;

TaskInformation tasks[NR_TASKS];
TaskInformation* lastUseI387;
TaskInformation* currentTask;

#endif /* _SCHEDULE_H */
